/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package deatax;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JComponent;
import javax.swing.UIManager;

/**
 *
 * @author nrechten
 */
public class LoadingLayer extends JComponent implements Runnable {

    private static Font FONT_MESSAGE = UIManager.getFont("Label.font").deriveFont(Font.BOLD, 20);

    private boolean mIsRunning;
    private boolean mIsFadingOut;
    private Timer mTimer;
    private String message;
    private int mAngle;
    private int mFadeCount;
    private int mFadeLimit = 15;

    public LoadingLayer() {
    }

    @Override
    public void paint(Graphics g) {
        int w = getWidth();
        int h = getHeight();

        // Paint the view.
        super.paint(g);

        if (!mIsRunning) {
            return;
        }

        Graphics2D g2 = (Graphics2D) g.create();

        float fade = (float) mFadeCount / (float) mFadeLimit;
        // Gray it out.
        Composite urComposite = g2.getComposite();
        g2.setComposite(AlphaComposite.getInstance( AlphaComposite.SRC_OVER, .5f * fade));
        g2.fillRect(0, 0, w, h);
        g2.setComposite(urComposite);

        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // Paint the wait indicator.
        int s = 20;
        int cx = w / 2;
        int cy = h / 2;

        g2.setFont(FONT_MESSAGE);
        int fh = g2.getFontMetrics().getHeight();
        int fw = g2.getFontMetrics().stringWidth(getMessage());
        g2.setPaint(Color.white);
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (4+(Math.abs((float)mAngle-6)/6))/5));
        g2.drawString(getMessage(), cx-fw/2,cy + s*2 + fh);


        g2.setStroke(new BasicStroke(s / 4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        g2.setPaint(Color.white);
//        g2.rotate(Math.PI * mAngle / 180, cx, cy);
        for (int i = 0; i < 12; i++) {
            float scale = (12.0f - (float) ((i + mAngle) % 12)) / 12.0f;
            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, scale * fade));
            g2.drawLine(cx + s, cy, cx + s * 2, cy);
            g2.rotate(-Math.PI / 6, cx, cy);
        }

        g2.dispose();
    }

    public void run() {

        if (mIsRunning) {
            mAngle += 1;
            if (mAngle >= 12) {
                mAngle = 0;
            }
            if (mIsFadingOut) {
                if (--mFadeCount == 0) {
                    mIsRunning = false;
                    mTimer.stop();
                }
            } else if (mFadeCount < mFadeLimit) {
                mFadeCount++;
            }
        }
        repaint();
    }

    public void start() {
        this.setMessage("Loading");

        this.setVisible(true);
        if (mIsRunning) {
            return;
        }

        // Run a thread for animation.
        mIsRunning = true;
        mIsFadingOut = false;
        mFadeCount = 0;
        int fps = 24;
        int tick = 1000 / fps;
        mTimer = new Timer(this, tick);
        mTimer.start();
    }

    public void stop() {
        mIsFadingOut = true;
    }


    /**
     * @return the message
     */
    public String getMessage() {
        return message;
    }

    /**
     * @param message the message to set
     */
    public void setMessage(String message) {
        this.message = message;
    }
}
